from django.db import models
from django.core.cache import cache
from django.db import transaction

# Create your models here.
from utils.basemodel import BaseModel


class Nav(BaseModel):
    name = models.CharField(max_length=50, verbose_name='导航名称')
    sort = models.IntegerField(verbose_name='排序', default=0)
    url = models.CharField(max_length=200, verbose_name='跳转路径')

    class Meta:
        db_table = 'mj_nav'

    def __str__(self):
        return self.name

    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)
        cache.delete('home:nav:list')

    def delete(self, *args, **kwargs):
        super().delete(*args, **kwargs)
        cache.delete('home:nav:list')


class Category(BaseModel):
    name = models.CharField(max_length=50, verbose_name='分类名称')
    level = models.IntegerField(verbose_name='分类级别', default=1)
    parent = models.ForeignKey(
        'self',
        verbose_name='父级分类',
        on_delete=models.CASCADE,
        blank=True,
        null=True
    )
    sort = models.IntegerField(verbose_name='排序', default=0)

    class Meta:
        db_table = 'mj_category'

    def __str__(self):
        return self.name

    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)
        cache.delete('home:category:list')

    def delete(self, *args, **kwargs):
        super().delete(*args, **kwargs)
        cache.delete('home:category:list')


class Banner(BaseModel):
    title = models.CharField(max_length=50, verbose_name='标题')
    imgUrl = models.CharField(max_length=200, verbose_name='图片路径')
    sort = models.IntegerField(verbose_name='排序', default=0)
    link = models.CharField(max_length=200, verbose_name='跳转路径')

    class Meta:
        db_table = 'mj_banner'

    def __str__(self):
        return self.title

    # 重写save 和 delete 删除缓存中的数据
    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)

        # 利用celery做延迟删除 在事务提交之后
        # cache.delete('home:banner:list')
        def _after_commit():  # 是一个钩子函数 本身不需要我们直接调用在 只要重写了_after_commit() 函数 在事务提交之后就会自动调用
            # 为什么要放在事务提交之后删除
            # 因为如果放在事务执行之前删除，如果事务回滚，那么缓存中的数据就没了
            # 如果放在事务提交之后删除，那么即使事务回滚， 缓存中的数据也不会丢失
            cache.delete('home:banner:list')  # 兜底操作 celery 的任务失败至少也会删除一次 第一次删除
            try:
                from .tasks import delete_cache_delay
                delete_cache_delay.apply_async(
                    args=[["home:banner:list"], 3],
                    countdown=0
                )
            except:
                pass

        transaction.on_commit(_after_commit)

    def delete(self, *args, **kwargs):
        super().delete(*args, **kwargs)

        # cache.delete('home:banner:list')
        def _after_commit():
            cache.delete('home:banner:list')
            try:
                from .tasks import delete_cache_delay
                delete_cache_delay.apply_async(
                    args=[["home:banner:list", 3]],
                    countdown=0
                )
            except:
                pass

        transaction.on_commit(_after_commit)
